package com.glink.manage.ftp;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.ObjectPool;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.NoSuchElementException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;


@Component
@Slf4j
public class FTPClientPool implements ObjectPool<SSLSessionReuseFTPSClient> {

    private static int DEFAULT_POOL_SIZE = 20;

    public BlockingQueue<SSLSessionReuseFTPSClient> blockingQueue;

    @Resource
    private FTPClientFactory factory;


    @PostConstruct
    public void initPool() throws IOException, InterruptedException {
        int poolSize = this.factory.ftpProperties.getDefaultPoolSize();
        poolSize = (poolSize <= 0) ? DEFAULT_POOL_SIZE : poolSize;
        if (poolSize < DEFAULT_POOL_SIZE) {
            DEFAULT_POOL_SIZE = poolSize;
        }
        this.blockingQueue = new ArrayBlockingQueue<>(poolSize);
        int count = 0;

        while (count < DEFAULT_POOL_SIZE) {
            addObject();
            count++;
        }
        log.info("初始化FTP连接池成功{}", Integer.valueOf(DEFAULT_POOL_SIZE));
    }


    public SSLSessionReuseFTPSClient borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = this.blockingQueue.poll();

        if (sslSessionReuseFTPSClient == null) {
            log.info("创建ftp为空 创建ftp ===============");
            sslSessionReuseFTPSClient = this.factory.create();
        } else if (!this.factory.validateObject(this.factory.wrap(sslSessionReuseFTPSClient))) {
            log.info("移除旧client {} ", sslSessionReuseFTPSClient.toString());
            invalidateObject(sslSessionReuseFTPSClient);
            sslSessionReuseFTPSClient = this.factory.create();
        }
        log.info("从连接池中获取 ftp :{}", sslSessionReuseFTPSClient.toString());
        return sslSessionReuseFTPSClient;
    }


    public void returnObject(SSLSessionReuseFTPSClient sslSessionReuseFTPSClient) {
        if (sslSessionReuseFTPSClient == null) {
            return;
        }
        try {
            sslSessionReuseFTPSClient.changeWorkingDirectory("/");
            if (!this.blockingQueue.offer(sslSessionReuseFTPSClient, 2L, TimeUnit.SECONDS)) {
                sslSessionReuseFTPSClient.disconnect();
                sslSessionReuseFTPSClient = null;
            }
        } catch (Exception e) {
            log.info("ftp连接返还失败");
        }
    }


    public void invalidateObject(SSLSessionReuseFTPSClient sslSessionReuseFTPSClient) throws Exception {
        this.blockingQueue.remove(sslSessionReuseFTPSClient);
    }


    public void addObject() throws IOException, InterruptedException {
        this.blockingQueue.offer(this.factory.create(), 2L, TimeUnit.SECONDS);
    }


    private void addObject(SSLSessionReuseFTPSClient client) throws InterruptedException {
        this.blockingQueue.offer(client, 2L, TimeUnit.SECONDS);
    }


    public SSLSessionReuseFTPSClient reconnect() throws Exception {
        return this.factory.create();
    }


    public int getNumIdle() {
        return this.blockingQueue.size();
    }


    public int getNumActive() {
        return DEFAULT_POOL_SIZE - getNumIdle();
    }


    public void clear() throws Exception, UnsupportedOperationException {
    }


    public void close() {
        try {
            while (this.blockingQueue.iterator().hasNext()) {
                SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = this.blockingQueue.poll();
                if (sslSessionReuseFTPSClient != null) {
                    this.factory.destroyObject(this.factory.wrap(sslSessionReuseFTPSClient));
                }
            }
        } catch (Exception e) {
            log.error("close ftp clent pool failed.....{}", e);
        }
    }
}

 